package cn.lg.soar.core.manager;

import cn.lg.soar.common.util.current.CurrentTokenInfo;
import cn.lg.soar.common.util.hardware.SystemUtils;
import cn.lg.soar.common.util.token.ISoarJWT;
import cn.lg.soar.common.util.token.SoarJWTFast;
import cn.lg.soar.core.model.AccessTokenProps;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 本地状态访问token管理器
 * @author luguoxiang 469599794@qq.com
 * @Date: 2025/5/17 14:48
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class LocalStateAccessTokenManager implements IStateAccessTokenManager{

    private static final Logger LOGGER = LoggerFactory.getLogger(LocalStateAccessTokenManager.class);
    private final ISoarJWT soarJWT;
    // 黑名单模式
    private final Cache<Long, Boolean> cache;

    public LocalStateAccessTokenManager(AccessTokenProps config) {
        long cacheSize = SystemUtils.getTotalMemory() >>> 16;
        this.cache = Caffeine.newBuilder()
                .maximumSize(cacheSize)
                .initialCapacity(128)
                .expireAfterWrite(config.getAccessTokenExpire())
                .build();
        LOGGER.info("token cache max size {}", cacheSize);
        this.soarJWT = new SoarJWTFast(config.getAccessTokenSecret(), config.getAccessTokenExpire());
    }

    /**
     * 创建token
     * @param payload 刷新token
     * @return 返回 accessToken
     */
    @Override
    public String create(String payload) {
        return soarJWT.create(payload);
    }

    /**
     * 验证token
     * @param accessToken
     * @return
     */
    @Override
    public CurrentTokenInfo verify(String accessToken) {
        String payload = soarJWT.verify(accessToken);
        if (payload == null) {
            return null;
        }
        CurrentTokenInfo currentTokenInfo = CurrentTokenInfo.valueOf(payload);
        Boolean value = cache.getIfPresent(currentTokenInfo.getTokenId());
        if (value == null) {
            return currentTokenInfo;
        };
        return null;
    }

    /**
     * 删除token
     * @param tokenId
     */
    @Override
    public void removeToken(long tokenId) {
        cache.put(tokenId, true);
    }

}
